package com.zrkizzy.common.limit.config;

import com.zrkizzy.common.limit.LimitManager;
import com.zrkizzy.common.limit.constant.LimitConst;
import com.zrkizzy.common.limit.strategy.GuavaLimit;
import com.zrkizzy.common.limit.strategy.RedisLimit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.script.DefaultRedisScript;

/**
 * 自定义限流配置类
 *
 * @author zhangrongkang
 * @since 2024/2/14
 */
@Configuration
@Slf4j
public class AccessLimitConfig {

    @Bean
    @ConditionalOnProperty(name = LimitConst.LIMIT_STRATEGY, havingValue = "guava")
    public LimitManager guavaLimiter(){
        log.info("load Guava limit strategy");
        return new GuavaLimit();
    }

    @Bean
    @ConditionalOnProperty(name = LimitConst.LIMIT_STRATEGY, havingValue = "redis")
    public LimitManager redisLimiter(){
        log.info("load Redis limit strategy");
        return new RedisLimit();
    }

    /**
     * Lua限流脚本
     *
     * @return Lua脚本
     */
    @Bean
    public DefaultRedisScript<Long> redisScript() {
        log.info("load redisLimit.lua limit script");
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        // redisLimit.lua脚本位置和application.yml同级目录
        redisScript.setLocation(new ClassPathResource("redisLimit.lua"));
        // 定义Lua脚本的返回值
        redisScript.setResultType(Long.class);
        return redisScript;
    }

}